use std::path::Path;
use aes::Aes256;
use aes::cipher::{KeyIvInit, StreamCipher};
use file_operand::get_all_volumes;
use hex::decode;
// use std::fs;
mod wall;
mod decrypt;
mod file_operand;

type Aes256Ctr = ctr::Ctr128BE<Aes256>;

// Important C Paths !
use dirs::{
    desktop_dir, 
    download_dir, 
    document_dir, 
    picture_dir, 
    audio_dir, 
    video_dir, 
};

fn main(){

    let dirs_to_decrypt = vec![
        desktop_dir(),
        download_dir(),
        document_dir(),
        picture_dir(),
        audio_dir(),
        video_dir(),
    ];

    for dir in dirs_to_decrypt.iter().flatten(){
        decryptor(dir);
    }

    // Decrypt volumes
    volume_paths();
    
    wall::set_wallpaper();
    println!("Decryption process completed.");
}

// Decrypt the main key
fn decrypt_combined_key(encrypted_key: &[u8], aes_key: &[u8; 32]) -> Result<Vec<u8>, &'static str> {
    if encrypted_key.len() < 16 {
        return Err("Invalid encrypted key length");
    }
    let aes_iv: [u8; 16] = encrypted_key[0..16].try_into().unwrap();
    let mut cipher = Aes256Ctr::new(aes_key.into(), &aes_iv.into());
    let mut decrypted_key = encrypted_key[16..].to_vec();
    cipher.apply_keystream(&mut decrypted_key);
    Ok(decrypted_key)
}

// Split the decrypted keys into the original components
fn split_keys(combined_key: &[u8]) -> ([u8; 32], [u8; 32], [u8; 12]) {
    let aes_key: [u8; 32] = combined_key[0..32].try_into().unwrap();
    let chacha_key: [u8; 32] = combined_key[32..64].try_into().unwrap();
    let chacha_nonce: [u8; 12] = combined_key[64..76].try_into().unwrap();
    (aes_key, chacha_key, chacha_nonce)
}

fn decrypt_hexa(keys: String)-> Vec<u8>{
    let dec_hexa = decode(keys).expect("Failed to decode Hex");
    let decrypt_vec_key: Vec<u8> = dec_hexa.iter().cloned().collect();

    decrypt_vec_key
}

fn decryptor(dir_path: &Path){

    let aes_key: [u8; 32] = [
        27, 20, 127, 230, 201, 208, 178, 24, 197, 76, 96, 12, 16, 47, 231, 42, 156, 36, 136, 165, 162, 223, 206, 190, 126, 59, 96, 99, 157, 122, 32, 165
    ];

    let ma1n_k3y = "58add3b1ecdd2a00d7f5f40fe04e46dff4beff64fa127f6a6b045d6788d58c1dd19675241841b5b15e4095ce39a01387609572d83acc5def7a04564ece79987a7b19cf1ecca6c5d672b91d94239079a30e7130a099fc7d9c8fc94d07".to_string();
    
    let v3c_value = decrypt_hexa(ma1n_k3y);
    
    let decrypted_keys = decrypt_combined_key(&v3c_value, &aes_key).unwrap();
    let (aes_key_dec, chacha_key, chacha_nonce) = split_keys(&decrypted_keys);

    file_operand::recursive_decrypt(
        &dir_path,
        &aes_key_dec,
        &chacha_key,
        &chacha_nonce,
    );
}

fn volume_paths(){
    if get_all_volumes().is_empty() {
        return;
    }
    
    for volume in get_all_volumes() {
        decryptor(Path::new(&volume));
    }
}